package com.magiccompass.alipay.barcode.controller;

import java.math.BigDecimal;
import java.net.URI;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.TreeMap;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.support.PagedListHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;

import com.magiccompass.alipay.barcode.constants.AlipayPartnerConstants;
import com.magiccompass.alipay.barcode.constants.BusinessLogicConstants;
import com.magiccompass.alipay.barcode.entity.AlipayQRCodeCreateRequest;
import com.magiccompass.alipay.barcode.entity.MerchantBankAccount;
import com.magiccompass.alipay.barcode.entity.MerchantEmails;
import com.magiccompass.alipay.barcode.entity.MerchantGroup;
import com.magiccompass.alipay.barcode.entity.MerchantInfo;
import com.magiccompass.alipay.barcode.entity.MerchantQRCode;
import com.magiccompass.alipay.barcode.entity.MerchantTransaction;
import com.magiccompass.alipay.barcode.entity.UserInfo;
import com.magiccompass.alipay.barcode.model.AlipayQRCodeCreateResponseModel;
import com.magiccompass.alipay.barcode.model.OperatorRoleModel;
import com.magiccompass.alipay.barcode.pageform.MerchantGroupAdminInutPageForm;
import com.magiccompass.alipay.barcode.pageform.MerchantGroupListPageForm;
import com.magiccompass.alipay.barcode.pageform.MerchantGroupQueryPageForm;
import com.magiccompass.alipay.barcode.pageform.MerchantInfoListPageForm;
import com.magiccompass.alipay.barcode.pageform.MerchantOperatorInutPageForm;
import com.magiccompass.alipay.barcode.pageform.MerchantOperatorListPageForm;
import com.magiccompass.alipay.barcode.pageform.MerchantOperatorQueryPageForm;
import com.magiccompass.alipay.barcode.pageform.MerchantQueryPageForm;
import com.magiccompass.alipay.barcode.pageform.MerchantTransactionListPageForm;
import com.magiccompass.alipay.barcode.pageform.TransactionQueryPageForm;
import com.magiccompass.alipay.barcode.pageform.UpdateMerchantInfoPageForm;
import com.magiccompass.alipay.barcode.responsehandler.QRCodeCreateResponseHandler;
import com.magiccompass.alipay.barcode.security.model.LoginUserModel;
import com.magiccompass.alipay.barcode.service.AlipayBarcodeService;
import com.magiccompass.alipay.barcode.service.MerchantBusinessService;
import com.magiccompass.alipay.barcode.service.UserService;
import com.magiccompass.alipay.barcode.signature.MD5Signature;
import com.magiccompass.alipay.barcode.util.AlipayBarcodeRequestUtil;
import com.magiccompass.alipay.barcode.util.CollectionUtil;
import com.magiccompass.alipay.barcode.util.DateTimeUtil;
import com.magiccompass.alipay.barcode.util.MerchantInfoUtil;
import com.magiccompass.alipay.barcode.util.MerchantTransactionUtil;
import com.magiccompass.alipay.barcode.util.OperatorRoleUtil;
import com.magiccompass.alipay.barcode.util.UrlUtil;
import com.magiccompass.alipay.barcode.util.UserUtil;

@Controller
@RequestMapping(value="/admin")
public class AdminController {
	static Logger logger = LogManager.getLogger(AdminController.class.getName());
	
	@Resource(name="alipayBarcodeService")
	private AlipayBarcodeService alipayBarcodeService;
	@Resource(name="merchantBusinessService")
	private MerchantBusinessService merchantBusinessService;
	@Resource(name="userService")
	private UserService userService;
	
	@RequestMapping(method = RequestMethod.GET)
    public ModelAndView home() {
        ModelAndView model = new ModelAndView("admin/home");
        return model;
    }
	
	@RequestMapping(value="/merchantList", method = {RequestMethod.GET,RequestMethod.POST})
    public String merchantList(@ModelAttribute("queryPageForm") MerchantQueryPageForm mqpf, Model model,HttpServletRequest request) {
		String submitType = request.getParameter("submitType");
		String paging = request.getParameter("paging");
		PagedListHolder<MerchantInfoListPageForm> plh = null;
		
		LinkedHashMap<String, String> activeFlagMap = new LinkedHashMap<String, String>();
		activeFlagMap.put("True", "True");
		activeFlagMap.put("False", "False");
		model.addAttribute("activeFlagList", activeFlagMap);
		if("q".equals(submitType)){ // user click query button
			String merchantName = mqpf.getMerchantName();
			String activeFlag = mqpf.getActiveFlag();
			if(merchantName == null || "".equals(merchantName)){
				merchantName = "%";
			}
			String delFlag = "%";
			if("True".equals(activeFlag)){
				delFlag = "F";
			}else if("False".equals(activeFlag)){
				delFlag = "T";
			}
			
			List<MerchantInfo> dbMIList = merchantBusinessService.findMerchantByNameAndDelFlag(merchantName, delFlag);
			if(dbMIList != null && dbMIList.size()>0){
				List<MerchantInfoListPageForm> pageList =  MerchantInfoUtil.makeMerchantInfoListPageForm(dbMIList);
				
				plh = new PagedListHolder<MerchantInfoListPageForm>(pageList);
				plh.setPage(0);
				plh.setPageSize(10);
				request.getSession().setAttribute("pagedListHolder", plh);
				model.addAttribute("pagedList", plh.getPageList());
			}else{
				request.getSession().setAttribute("pagedListHolder", new PagedListHolder<MerchantInfoListPageForm>());
			}
		}else{ // default
			mqpf.setActiveFlag("True");
			List<MerchantInfo> defaultMerchantList = merchantBusinessService.findAllActiveMerchant();
			if("t".equals(paging)){ // user click page
				String page = request.getParameter("page");
				plh = (PagedListHolder<MerchantInfoListPageForm>)request.getSession().getAttribute("pagedListHolder");
				if ("next".equals(page)){
					plh.nextPage();
				}else if ("previous".equals(page)){
					plh.previousPage();
				}
				model.addAttribute("pagedList", plh.getPageList());
			}else if(defaultMerchantList != null &&defaultMerchantList.size()>0){
				List<MerchantInfoListPageForm> pageList =  MerchantInfoUtil.makeMerchantInfoListPageForm(defaultMerchantList);
				
				plh = new PagedListHolder<MerchantInfoListPageForm>(pageList);
				plh.setPage(0);
				plh.setPageSize(10);
				request.getSession().setAttribute("pagedListHolder", plh);
				model.addAttribute("pagedList", plh.getPageList());
			}else{
				request.getSession().setAttribute("pagedListHolder", new PagedListHolder<MerchantInfoListPageForm>());
			}
		}
		
		return "admin/merchantList";
    }
	
	@RequestMapping(value="/createQRCode", method = {RequestMethod.GET,RequestMethod.POST})
    public String createQRCode(Model model,HttpServletRequest request) {
		String merchantId = request.getParameter("merchantId");
		try{
			LoginUserModel currentUser = UserUtil.getCurrentLoginUser();
			MerchantInfo mi = merchantBusinessService.findMerchantById(Integer.parseInt(merchantId));
			
			MerchantQRCode qrCode = alipayBarcodeService.findMerchantQRCodeByMerchantId(Integer.parseInt(merchantId));
			if(qrCode == null){ // There is no QR code record for this merchant
				AlipayQRCodeCreateRequest aqrccr = AlipayBarcodeRequestUtil.alipayBarcodeCreateRequestEntityInit(mi,currentUser.getLoginUserId());
				TreeMap<String,String> barcodeRequestParameter4AlipayTreeMap = AlipayBarcodeRequestUtil.makeParameterMap4Alipay(aqrccr,alipayBarcodeService);
				String sign = AlipayBarcodeRequestUtil.getSign(barcodeRequestParameter4AlipayTreeMap);
				
				aqrccr.setSign(sign);
				alipayBarcodeService.save(aqrccr);
				
				barcodeRequestParameter4AlipayTreeMap.put("sign", aqrccr.getSign());
				barcodeRequestParameter4AlipayTreeMap.put("sign_type", AlipayPartnerConstants.SIGN_TYPE);
				
				if(aqrccr.getId() != null){ // success insert into DB
					try {					
						RestTemplate restTemplate = new RestTemplate();
						
						String alipayBarcodeServerURL = AlipayPartnerConstants.ALIPAY_GATEWAY;
				    	String alipayBarcodeParameter = UrlUtil.makeParameterMap2String(barcodeRequestParameter4AlipayTreeMap);
				    	String restURL = alipayBarcodeServerURL+"?"+alipayBarcodeParameter;
				    	logger.info("restURL:"+restURL);
				    	URI uri = new URI(restURL);
						//String response = restTemplate.getForObject(restURL, String.class);
				    	String response = restTemplate.getForObject(uri, String.class);
				    	//String response = PaymentResponseHandler.RESULT_FAILEDFAIED_4_TEST;
						logger.info("response is:"+response);
						
						AlipayQRCodeCreateResponseModel alipayResponse = QRCodeCreateResponseHandler.handleResponse(response, aqrccr, alipayBarcodeService);
						
						MerchantQRCode mqrCode = new MerchantQRCode();
						mqrCode.setMerchant(mi);
						mqrCode.setCreateBy(BusinessLogicConstants.SYSTEM_CREATOR_ID);
						mqrCode.setQrCode(alipayResponse.getQrCode());
						mqrCode.setQrcodeImgUrl(alipayResponse.getQrCodeImgUrl());
						alipayBarcodeService.save(mqrCode);
						
						model.addAttribute("message","QRCode successful made.");
						model.addAttribute("messageType","alert-success");
						model.addAttribute("qrCode",alipayResponse.getQrCode());
						model.addAttribute("qrCodeImgUrl",alipayResponse.getQrCodeImgUrl());
					} catch (Exception e) {
						model.addAttribute("message","Make QRCode failed, please contact administrator.");
						model.addAttribute("messageType","alert-danger");
						e.printStackTrace();
					}
				}
			}else{
				model.addAttribute("message","QRCode already exist.");
				model.addAttribute("messageType","alert-warning");
				model.addAttribute("qrCode",qrCode.getQrCode());
				model.addAttribute("qrCodeImgUrl",qrCode.getQrcodeImgUrl());
			}
		}catch(Exception e){
			model.addAttribute("message","Make QRCode failed, please contact administrator.");
			model.addAttribute("messageType","alert-danger");
			e.printStackTrace();
		}
		return "common/createQRCodeResult";
    }
	
	@RequestMapping(value="/addMerchantInit", method = {RequestMethod.GET,RequestMethod.POST})
    public String addMerchantInit(Model model,HttpServletRequest request) {
		return "admin/addMerchantInit";
    }
	
	@RequestMapping(value="/merchantEnableDisable", method = {RequestMethod.GET,RequestMethod.POST})
    public String merchantEnableDisable(Model model,HttpServletRequest request) {
		String resultCode = "SUCCESS";
		String resultReason = "Please continue.";
		
		String merchantId = request.getParameter("merchantId");
		
		try{
			MerchantInfo mi = merchantBusinessService.findMerchantById(Integer.parseInt(merchantId));
			if("T".equals(mi.getDelFlag())){
				mi.setDelFlag("F");
			}else if("F".equals(mi.getDelFlag())){
				mi.setDelFlag("T");
			}
			merchantBusinessService.save(mi);
		}catch(Exception e){
			resultCode = "FAILED";
			resultReason = e.getMessage();
			e.printStackTrace();
		}

		String messageType = "alert-danger";
		if("SUCCESS".equals(resultCode)){
			messageType = "alert-success";
		}
		
		String message = "Your operation result is "+resultCode+". "+resultReason;
		
		model.addAttribute("message",message);
		model.addAttribute("messageType",messageType);
		return "common/result";
    }
	
	@RequestMapping(value="/addMerchantComplete", method = {RequestMethod.GET,RequestMethod.POST})
    public String addMerchantComplete(Model model,HttpServletRequest request) {
		String merchantName = request.getParameter("merchantName");
		String email = request.getParameter("email");
		String displayName = request.getParameter("displayName");
		String industry = request.getParameter("industry");
		String feeRate = request.getParameter("feeRate");
		
		MerchantInfo mi = new MerchantInfo();
		mi.setMerchantName(merchantName);
		mi.setEmail(email);
		mi.setDisplayName(displayName);
		mi.setIndustry(industry);
		mi.setFeeRate(new BigDecimal(feeRate));
		mi.setCreateBy(BusinessLogicConstants.SYSTEM_CREATOR_ID);
		
		String accountName = request.getParameter("accountName");
		String accountNumber = request.getParameter("accountNumber");
		String bankType = request.getParameter("bankType");
		String bankBranchName = request.getParameter("bankBranchName");
		String currency = request.getParameter("currency");
		
		MerchantBankAccount mba = new MerchantBankAccount();
		mba.setAccountName(accountName);
		mba.setAccountNumber(accountNumber);
		mba.setBankType(bankType);
		mba.setBankBranchName(bankBranchName);
		mba.setCurrency(currency);
		mba.setDefaultFlag("T");
		
		mi.addMerchantBankAccount(mba);
		
		String[] merchantEmails = request.getParameterValues("supportEmail");
		if(merchantEmails != null){
			for(String aSupportEmail:merchantEmails){
				if(aSupportEmail != null && !aSupportEmail.isEmpty()){
					MerchantEmails me = new MerchantEmails();
					me.setEmailAddress(aSupportEmail);
					mi.addMerchantEmails(me);
				}
			}
		}		
		
		String resultCode = "SUCCESS";
		String resultReason = "Please continue.";
		
		try{
			merchantBusinessService.save(mi);
		}catch(Exception e){
			resultCode = "FAILED";
			resultReason = e.getMessage();
			e.printStackTrace();
		}

		String messageType = "alert-danger";
		if("SUCCESS".equals(resultCode)){
			messageType = "alert-success";
		}
		
		String message = "Your operation result is "+resultCode+". "+resultReason;
		
		model.addAttribute("message",message);
		model.addAttribute("messageType",messageType);
		return "common/result";
    }
	
	@RequestMapping(value="/updateMerchantInit", method = {RequestMethod.GET,RequestMethod.POST})
    public String updateMerchantInit(Model model,HttpServletRequest request) {
		String merchantId = request.getParameter("merchantId");
		MerchantInfo mi = merchantBusinessService.findMerchantById(Integer.parseInt(merchantId));
		List<MerchantBankAccount> allMerchantBankAccount = merchantBusinessService.findAllActiveMerchantBankAccount(Integer.parseInt(merchantId));
		List<MerchantEmails> allMerchantSupportEmails = merchantBusinessService.findAllActiveMerchantSupportEmails(Integer.parseInt(merchantId));
		
		UpdateMerchantInfoPageForm umipf;
		if(allMerchantBankAccount != null && allMerchantBankAccount.size()>0){
			umipf = MerchantInfoUtil.makeUpdateMerchantInfoPageForm(mi, allMerchantBankAccount.get(0));
			model.addAttribute("modelBankType", allMerchantBankAccount.get(0).getBankType());
			model.addAttribute("modelIndustry", mi.getIndustry());
		}else{
			umipf = MerchantInfoUtil.makeUpdateMerchantInfoPageForm(mi, null);
			model.addAttribute("modelBankType", "");
			model.addAttribute("modelIndustry", mi.getIndustry());
		}
		
		if(allMerchantSupportEmails != null && allMerchantSupportEmails.size()>0){
			List<String> supportEmails = new ArrayList<String>();
			for(MerchantEmails me:allMerchantSupportEmails){
				supportEmails.add(me.getEmailAddress());
			}
			model.addAttribute("supportEmails", supportEmails);
		}
			
		model.addAttribute("updatePageForm",umipf);
		return "admin/updateMerchantInit";
    }
	
	@RequestMapping(value="/updateMerchantComplete", method = {RequestMethod.GET,RequestMethod.POST})
    public String updateMerchantComplete(@ModelAttribute("updatePageForm") UpdateMerchantInfoPageForm um,Model model,HttpServletRequest request) {
		Integer updateMerchantId = um.getId();
		merchantBusinessService.removeAllActiveMerchantSupportEmails(updateMerchantId);
		MerchantInfo mi = merchantBusinessService.findMerchantById(updateMerchantId);
		
		mi.setMerchantName(um.getMerchantName());
		mi.setEmail(um.getEmail());
		mi.setDisplayName(um.getDisplayName());
		mi.setIndustry(um.getIndustry());
		mi.setFeeRate(new BigDecimal(um.getFeeRate()));
		LoginUserModel currentUser = UserUtil.getCurrentLoginUser();
		mi.setUpdateby(currentUser.getLoginUserId());
		mi.setUpdateTime(DateTimeUtil.getCurrentTimestamp());
		
		List<MerchantBankAccount> allMerchantBankAccount = merchantBusinessService.findAllActiveMerchantBankAccount(updateMerchantId);
		MerchantBankAccount mba;
		if(allMerchantBankAccount != null && allMerchantBankAccount.size()>0){
			mba = allMerchantBankAccount.get(0);
			mba.setUpdateby(currentUser.getLoginUserId());
			mba.setUpdateTime(DateTimeUtil.getCurrentTimestamp());
		}else{
			mba = new MerchantBankAccount();			
		}
		
		mba.setAccountName(um.getAccountName());
		mba.setAccountNumber(um.getAccountNumber());
		mba.setBankType(um.getBankType());
		mba.setBankBranchName(um.getBankBranchName());
		mba.setCurrency(um.getCurrency());
		mba.setDefaultFlag("T");
		
		mi.removeAllMerchantBankAccount();
		mi.addMerchantBankAccount(mba);
		
		String[] merchantEmails = request.getParameterValues("supportEmail");
		
		if(merchantEmails != null){
			mi.setMerchantEmails(new ArrayList<MerchantEmails>());
			for(String aSupportEmail:merchantEmails){
				if(aSupportEmail != null && !aSupportEmail.isEmpty()){
					MerchantEmails me = new MerchantEmails();
					me.setEmailAddress(aSupportEmail);
					mi.addMerchantEmails(me);
				}
			}
		}		
		
		String resultCode = "SUCCESS";
		String resultReason = "Please continue.";
		
		try{
			merchantBusinessService.save(mi);
		}catch(Exception e){
			resultCode = "FAILED";
			resultReason = e.getMessage();
			e.printStackTrace();
		}

		String messageType = "alert-danger";
		if("SUCCESS".equals(resultCode)){
			messageType = "alert-success";
		}
		
		String message = "Your operation result is "+resultCode+". "+resultReason;
		
		model.addAttribute("message",message);
		model.addAttribute("messageType",messageType);
		return "common/result";
    }
	
	@RequestMapping(value="/merchantOperatorList", method = {RequestMethod.GET,RequestMethod.POST})
    public String merchantOperatorList(@ModelAttribute("queryPageForm") MerchantOperatorQueryPageForm moqpf, Model model,HttpServletRequest request) {
		String submitType = request.getParameter("submitType");
		String paging = request.getParameter("paging");
		PagedListHolder<MerchantOperatorListPageForm> plh = null;
		
		LinkedHashMap<String, String> activeFlagMap = new LinkedHashMap<String, String>();
		activeFlagMap.put("True", "True");
		activeFlagMap.put("False", "False");
		model.addAttribute("activeFlagList", activeFlagMap);
		
		List<MerchantInfo> allMerchantList = merchantBusinessService.findAllActiveMerchant();
		model.addAttribute("merchantList",CollectionUtil.transferMerchantList(allMerchantList));
		
		if("q".equals(submitType)){ // user click query button
			String operatorName = moqpf.getOperatorName();
			String activeFlag = moqpf.getActiveFlag();
			if(operatorName == null || "".equals(operatorName)){
				operatorName = "%";
			}
			String delFlag = "%";
			if("True".equals(activeFlag)){
				delFlag = "F";
			}else if("False".equals(activeFlag)){
				delFlag = "T";
			}
			
			String merchantId = moqpf.getMerchantId().toString();
			if("0".equals(merchantId)){
				merchantId = "%";
			}
			
			List<UserInfo> dbMIList = merchantBusinessService.findMerchantOperatorByNameAndMerchantIdAndDelFlag(operatorName,merchantId, delFlag);
			if(dbMIList != null && dbMIList.size()>0){
				List<MerchantOperatorListPageForm> pageList =  MerchantInfoUtil.makeMerchantOperatorListPageForm(dbMIList);
				
				plh = new PagedListHolder<MerchantOperatorListPageForm>(pageList);
				plh.setPage(0);
				plh.setPageSize(10);
				request.getSession().setAttribute("pagedListHolder", plh);
				model.addAttribute("pagedList", plh.getPageList());
			}else{
				request.getSession().setAttribute("pagedListHolder", new PagedListHolder<MerchantOperatorListPageForm>());
			}
		}else if("t".equals(paging)){ // user click page
			String page = request.getParameter("page");
			plh = (PagedListHolder<MerchantOperatorListPageForm>)request.getSession().getAttribute("pagedListHolder");
			if ("next".equals(page)){
				plh.nextPage();
			}else if ("previous".equals(page)){
				plh.previousPage();
			}
			model.addAttribute("pagedList", plh.getPageList());
		}else{ // default
			
		}
		
		return "admin/merchantOperatorList";
    }
	
	@RequestMapping(value="/merchantOperatorEnableDisable", method = {RequestMethod.GET,RequestMethod.POST})
    public String merchantOperatorEnableDisable(Model model,HttpServletRequest request) {
		String resultCode = "SUCCESS";
		String resultReason = "Please continue.";
		
		String operatorId = request.getParameter("operatorId");
		
		try{
			UserInfo ui = merchantBusinessService.findMerchantOperatorById(Integer.parseInt(operatorId));
			if("T".equals(ui.getDelFlag())){
				ui.setDelFlag("F");
			}else if("F".equals(ui.getDelFlag())){
				ui.setDelFlag("T");
			}
			merchantBusinessService.save(ui);
		}catch(Exception e){
			resultCode = "FAILED";
			resultReason = e.getMessage();
			e.printStackTrace();
		}

		String messageType = "alert-danger";
		if("SUCCESS".equals(resultCode)){
			messageType = "alert-success";
		}
		
		String message = "Your operation result is "+resultCode+". "+resultReason;
		
		model.addAttribute("message",message);
		model.addAttribute("messageType",messageType);
		return "common/result";
    }
	
	@RequestMapping(value="/addMerchantOperatorInit", method = {RequestMethod.GET,RequestMethod.POST})
    public String addMerchantOperatorInit(Model model,HttpServletRequest request) {
		List<MerchantInfo> allMerchantList = merchantBusinessService.findAllActiveMerchant();
		model.addAttribute("merchantList",CollectionUtil.transferMerchantList(allMerchantList));
		model.addAttribute("roleList",OperatorRoleUtil.getInstance().getRoleMap());
		model.addAttribute("addmerchantOperatorForm",new MerchantOperatorInutPageForm());
		return "admin/addMerchantOperatorInit";
    }
	
	@RequestMapping(value="/addMerchantOperatorComplete", method = {RequestMethod.GET,RequestMethod.POST})
    public String addMerchantOperatorComplete(@ModelAttribute("addmerchantOperatorForm") MerchantOperatorInutPageForm moipf,Model model,HttpServletRequest request) {
		String operatorName = moipf.getOperatorName();
		String password = moipf.getPassword();
		String confirmPassword = moipf.getConfirmPassword();
		Integer merchantId = moipf.getMerchantId();
		
		Integer roleId = moipf.getRoleId();

		String resultCode = "SUCCESS";
		String resultReason = "Please continue.";
		
		if(!password.equals(confirmPassword)){
			resultCode = "FAILED";
			resultReason = "Sorry, you have input different password.";
		}else{
			try{
				UserInfo ui = new UserInfo();
				ui.setUserName(operatorName);
				//ui.setRoleId(2);
				ui.setRoleId(roleId);
				ui.setPassword(MD5Signature.getMD5String(password));
				ui.setMerchant(merchantBusinessService.findMerchantById(merchantId));
				
				merchantBusinessService.save(ui);
			}catch(Exception e){
				resultCode = "FAILED";
				resultReason = e.getMessage();
				e.printStackTrace();
			}
		}

		String messageType = "alert-danger";
		if("SUCCESS".equals(resultCode)){
			messageType = "alert-success";
		}
		
		String message = "Your operation result is "+resultCode+". "+resultReason;
		
		model.addAttribute("message",message);
		model.addAttribute("messageType",messageType);
		return "common/result";
    }
	
	@RequestMapping(value="/updateMerchantOperatorInit", method = {RequestMethod.GET,RequestMethod.POST})
    public String updateMerchantOperatorInit(Model model,HttpServletRequest request) {
		String operatorId = request.getParameter("operatorId");
		UserInfo ui = userService.findUserInfoByUserId(Integer.parseInt(operatorId));
		MerchantOperatorInutPageForm moipf = new MerchantOperatorInutPageForm();
		moipf.setId(Integer.parseInt(operatorId));
		moipf.setOperatorName(ui.getUserName());
		moipf.setRoleId(ui.getRoleId());
		
		model.addAttribute("updatePageForm",moipf);
		model.addAttribute("roleList",OperatorRoleUtil.getInstance().getRoleMap());
		model.addAttribute("merchantName", ui.getMerchant().getDisplayName());
		return "admin/updateMerchantOperatorInit";
    }
	
	@RequestMapping(value="/updateMerchantOperatorComplete", method = {RequestMethod.GET,RequestMethod.POST})
    public String updateMerchantOperatorComplete(@ModelAttribute("updatePageForm") MerchantOperatorInutPageForm moipf,Model model,HttpServletRequest request) {
		Integer updateOperatorId = moipf.getId();
		UserInfo ui = userService.findUserInfoByUserId(updateOperatorId);
		
		String operatorName = moipf.getOperatorName();
		String password = moipf.getPassword();
		String confirmPassword = moipf.getConfirmPassword();
		
		Integer roleId = moipf.getRoleId();

		String resultCode = "SUCCESS";
		String resultReason = "Please continue.";
		try{
			if(password != null && password.isEmpty() && confirmPassword != null && confirmPassword.isEmpty()){
				ui.setUserName(operatorName);
				ui.setRoleId(roleId);
			}else if(!password.equals(confirmPassword)){
				resultCode = "FAILED";
				resultReason = "Sorry, you have input different password.";
			}else{
				ui.setUserName(operatorName);
				ui.setRoleId(roleId);
				ui.setPassword(MD5Signature.getMD5String(password));
			}
			merchantBusinessService.save(ui);
		}catch(Exception e){
			resultCode = "FAILED";
			resultReason = e.getMessage();
			e.printStackTrace();
		}

		String messageType = "alert-danger";
		if("SUCCESS".equals(resultCode)){
			messageType = "alert-success";
		}
		
		String message = "Your operation result is "+resultCode+". "+resultReason;
		
		model.addAttribute("message",message);
		model.addAttribute("messageType",messageType);
		return "common/result";
    }
	
	@RequestMapping(value="/transactionQuery", method = {RequestMethod.GET,RequestMethod.POST})
    public ModelAndView transactionQuery(@ModelAttribute("queryPageForm") TransactionQueryPageForm tqpf, Model model,HttpServletRequest request) {
		String submitType = request.getParameter("submitType");
		String paging = request.getParameter("paging");
		PagedListHolder<MerchantTransactionListPageForm> plh = null;
		
		List<MerchantInfo> allMerchantList = merchantBusinessService.findAllActiveMerchant();
		model.addAttribute("merchantList",CollectionUtil.transferMerchantList(allMerchantList));
		
		if("q".equals(submitType)){ // user click query button
			String fromDate = tqpf.getFromDate();
			String toDate = tqpf.getToDate();
			String merchantId = tqpf.getMerchantId().toString();
			if("0".equals(merchantId)){
				merchantId = "%";
			}
			
			Timestamp fromTimestamp = DateTimeUtil.getTimestampFromStringByFormat(fromDate, "yyyy-MM-dd");
			Timestamp toTimestamp = DateTimeUtil.getTimestampFromStringByFormat(toDate, "yyyy-MM-dd");
			Calendar calendar = Calendar.getInstance();
			calendar.setTimeInMillis(toTimestamp.getTime());
			calendar.setTimeInMillis(calendar.getTimeInMillis());
			calendar.add(Calendar.DATE, 1); // because toDate return only yyyy-mm-dd, we need add one more day to include toDate.
			
			long fromTimestampMS = fromTimestamp.getTime();
			long toTimestampMS = calendar.getTimeInMillis();
			
			List<MerchantTransaction> dbMTList = merchantBusinessService.getMerchantTransactionListByTime(fromTimestampMS, toTimestampMS, merchantId);
			if(dbMTList != null && dbMTList.size()>0){
				List<MerchantTransactionListPageForm> pageList =  MerchantTransactionUtil.makeMerchantTransactionListPageForm(dbMTList);
				
				plh = new PagedListHolder<MerchantTransactionListPageForm>(pageList);
				plh.setPage(0);
				plh.setPageSize(10);
				request.getSession().setAttribute("pagedListHolder", plh);
				model.addAttribute("pagedList", plh.getPageList());
			}else{
				request.getSession().setAttribute("pagedListHolder", new PagedListHolder<MerchantTransactionListPageForm>());
			}
		}else if("t".equals(paging)){ // user click page
			String page = request.getParameter("page");
			plh = (PagedListHolder<MerchantTransactionListPageForm>)request.getSession().getAttribute("pagedListHolder");
			if ("next".equals(page)){
				plh.nextPage();
			}else if ("previous".equals(page)){
				plh.previousPage();
			}
			model.addAttribute("pagedList", plh.getPageList());
		}else{ // default
			
		}
		return new ModelAndView("admin/transactionQueryList");
    }
	
	@RequestMapping(value="/merchantGroupList", method = {RequestMethod.GET,RequestMethod.POST})
    public String merchantGroupList(@ModelAttribute("queryPageForm") MerchantGroupQueryPageForm mqpf, Model model,HttpServletRequest request) {
		String submitType = request.getParameter("submitType");
		String paging = request.getParameter("paging");
		PagedListHolder<MerchantGroupListPageForm> plh = null;
		
		LinkedHashMap<String, String> activeFlagMap = new LinkedHashMap<String, String>();
		activeFlagMap.put("True", "True");
		activeFlagMap.put("False", "False");
		model.addAttribute("activeFlagList", activeFlagMap);
		if("q".equals(submitType)){ // user click query button
			String merchantGroupName = mqpf.getMerchantGroupName();
			if(merchantGroupName == null || "".equals(merchantGroupName)){
				merchantGroupName = "%";
			}
			
			
			List<MerchantGroup> dbMIList = merchantBusinessService.findMerchantGroupByName(merchantGroupName);
			if(dbMIList != null && dbMIList.size()>0){
				List<MerchantGroupListPageForm> pageList =  MerchantInfoUtil.makeMerchantGroupListPageForm(dbMIList);
				
				plh = new PagedListHolder<MerchantGroupListPageForm>(pageList);
				plh.setPage(0);
				plh.setPageSize(10);
				request.getSession().setAttribute("pagedListHolder", plh);
				model.addAttribute("pagedList", plh.getPageList());
			}else{
				request.getSession().setAttribute("pagedListHolder", new PagedListHolder<MerchantGroupListPageForm>());
			}
		}else{ // default
			List<MerchantGroup> defaultMerchantList = merchantBusinessService.findAllMerchantGroup();
			if("t".equals(paging)){ // user click page
				String page = request.getParameter("page");
				plh = (PagedListHolder<MerchantGroupListPageForm>)request.getSession().getAttribute("pagedListHolder");
				if ("next".equals(page)){
					plh.nextPage();
				}else if ("previous".equals(page)){
					plh.previousPage();
				}
				model.addAttribute("pagedList", plh.getPageList());
			}else if(defaultMerchantList != null &&defaultMerchantList.size()>0){
				List<MerchantGroupListPageForm> pageList =  MerchantInfoUtil.makeMerchantGroupListPageForm(defaultMerchantList);
				
				plh = new PagedListHolder<MerchantGroupListPageForm>(pageList);
				plh.setPage(0);
				plh.setPageSize(10);
				request.getSession().setAttribute("pagedListHolder", plh);
				model.addAttribute("pagedList", plh.getPageList());
			}else{
				request.getSession().setAttribute("pagedListHolder", new PagedListHolder<MerchantGroupListPageForm>());
			}
		}		
		return "admin/merchantGroupList";
    }
	
	@RequestMapping(value="/addMerchantGroupInit", method = {RequestMethod.GET,RequestMethod.POST})
    public String addMerchantGroupInit(Model model,HttpServletRequest request) {
		List<MerchantInfo> defaultMerchantList = merchantBusinessService.findAllActiveMerchant();
		List<MerchantInfoListPageForm> pageList =  MerchantInfoUtil.makeMerchantInfoListPageForm(defaultMerchantList);
		model.addAttribute("merchantList", pageList);
		return "admin/addMerchantGroupInit";
    }
	
	@RequestMapping(value="/addMerchantGroupComplete", method = {RequestMethod.GET,RequestMethod.POST})
    public String addMerchantGroupComplete(Model model,HttpServletRequest request) {
		String merchantGroupName = request.getParameter("merchantGroupName");
		String[] selectedMerchantId = request.getParameterValues("selectedMerchant");
		
		String resultCode = "SUCCESS";
		String resultReason = "Please continue.";
		
		try {
			MerchantGroup mg = new MerchantGroup();
			mg.setGroupName(merchantGroupName);
			mg.setCreateBy(UserUtil.getCurrentLoginUser().getLoginUserId());
			MerchantInfo mi = null;
			for(String aMechantId:selectedMerchantId){
				mi = merchantBusinessService.findMerchantById(Integer.parseInt(aMechantId));
				mg.addMerchant(mi);
			}
			merchantBusinessService.save(mg);
		} catch (NumberFormatException e) {
			resultCode = "FAILED";
			resultReason = e.getMessage();
			e.printStackTrace();
		}
		
		String messageType = "alert-danger";
		if("SUCCESS".equals(resultCode)){
			messageType = "alert-success";
		}
		
		String message = "Your operation result is "+resultCode+". "+resultReason;
		
		model.addAttribute("message",message);
		model.addAttribute("messageType",messageType);		
		return "common/result";
    }
	@RequestMapping(value="/updateMerchantGroupInit", method = {RequestMethod.GET,RequestMethod.POST})
    public String updateMerchantGroupInit(Model model,HttpServletRequest request) {
		
		String merchantGroupId = request.getParameter("merchantGroupId");
		MerchantGroup mg = merchantBusinessService.findMerchantGroupById(Integer.parseInt(merchantGroupId));
		model.addAttribute("merchantGroupName", mg.getGroupName());
		model.addAttribute("merchantGroupId", mg.getId());
		List<MerchantInfo> dbSelectedMerchantList = merchantBusinessService.findMerchantByGroupId(Integer.parseInt(merchantGroupId));
		List<MerchantInfoListPageForm> selectedMerchantList =  MerchantInfoUtil.makeMerchantInfoListPageForm(dbSelectedMerchantList);
		model.addAttribute("selectedMerchantList", selectedMerchantList);		
		List<MerchantInfo> defaultMerchantList = merchantBusinessService.findAllActiveMerchant();
		List<MerchantInfoListPageForm> pageList =  MerchantInfoUtil.makeMerchantInfoListPageForm(defaultMerchantList);
		model.addAttribute("merchantList", removeDBSelectedMerchant(pageList,selectedMerchantList));
		return "admin/updateMerchantGroupInit";
    }
	
	@RequestMapping(value="/updateMerchantGroupComplete", method = {RequestMethod.GET,RequestMethod.POST})
    public String updateMerchantGroupComplete(Model model,HttpServletRequest request) {
		String merchantGroupName = request.getParameter("merchantGroupName");
		String[] selectedMerchantId = request.getParameterValues("selectedMerchant");
		String merchantGroupId = request.getParameter("merchantGroupId");
		
		String resultCode = "SUCCESS";
		String resultReason = "Please continue.";
		
		try {
			List<MerchantInfo> dbSelectedMerchantList = merchantBusinessService.findMerchantByGroupId(Integer.parseInt(merchantGroupId));
			for(MerchantInfo mi:dbSelectedMerchantList){
				mi.setMerchantGroup(null);
				merchantBusinessService.save(mi);
			}
			
			MerchantGroup mg = merchantBusinessService.findMerchantGroupById(Integer.parseInt(merchantGroupId));
			mg.setGroupName(merchantGroupName);
			mg.setUpdateby(UserUtil.getCurrentLoginUser().getLoginUserId());
			mg.setUpdateTime(DateTimeUtil.getCurrentTimestamp());
			mg.setMerchants(new HashSet<MerchantInfo>());
			MerchantInfo mi = null;
			for(String aMechantId:selectedMerchantId){
				mi = merchantBusinessService.findMerchantById(Integer.parseInt(aMechantId));
				mg.addMerchant(mi);
			}
			merchantBusinessService.save(mg);
		} catch (NumberFormatException e) {
			resultCode = "FAILED";
			resultReason = e.getMessage();
			e.printStackTrace();
		}
		
		String messageType = "alert-danger";
		if("SUCCESS".equals(resultCode)){
			messageType = "alert-success";
		}
		
		String message = "Your operation result is "+resultCode+". "+resultReason;
		
		model.addAttribute("message",message);
		model.addAttribute("messageType",messageType);		
		return "common/result";
    }
	
	@RequestMapping(value="/result", method = {RequestMethod.GET,RequestMethod.POST})
    public String result(Model model,HttpServletRequest request) {
		String resultCode = request.getParameter("resultCode");
		String resultReason = request.getParameter("resultReason");
		
		String messageType = "alert-danger";
		if("SUCCESS".equals(resultCode)){
			messageType = "alert-success";
		}
		
		String message = "Your operation result is "+resultCode+". "+resultReason;
		
		model.addAttribute("message",message);
		model.addAttribute("messageType",messageType);
		return "common/result";
    }
	
	@RequestMapping(value="/merchantOperatorInit", method = {RequestMethod.GET,RequestMethod.POST})
    public String merchantOperatorInit(Model model,HttpServletRequest request) {
		return "admin/merchantOperatorInit";
    }
	
	private List<MerchantInfoListPageForm> removeDBSelectedMerchant(List<MerchantInfoListPageForm> allMerchantList, List<MerchantInfoListPageForm> selectedMerchantList){
		List<MerchantInfoListPageForm> returnList = new ArrayList<MerchantInfoListPageForm>();
		boolean isSelected = false;
		for(MerchantInfoListPageForm allMerchant:allMerchantList){
			isSelected = false;
			for(MerchantInfoListPageForm selectedMerchant:selectedMerchantList){
				if(selectedMerchant.getId().equals(allMerchant.getId())){
					isSelected = true;
					break;
				}
			}
			if(!isSelected){
				returnList.add(allMerchant);
			}
		}
		return returnList;
	}

	@RequestMapping(value="/merchantGroupAdminList", method = {RequestMethod.GET,RequestMethod.POST})
	public String merchantGroupAdminList(@ModelAttribute("queryPageForm") MerchantOperatorQueryPageForm moqpf, Model model,HttpServletRequest request) {
		String submitType = request.getParameter("submitType");
		String paging = request.getParameter("paging");
		PagedListHolder<MerchantOperatorListPageForm> plh = null;
		
		LinkedHashMap<String, String> activeFlagMap = new LinkedHashMap<String, String>();
		activeFlagMap.put("True", "True");
		activeFlagMap.put("False", "False");
		model.addAttribute("activeFlagList", activeFlagMap);
		
		if("q".equals(submitType)){ // user click query button
			String operatorName = moqpf.getOperatorName();
			String activeFlag = moqpf.getActiveFlag();
			if(operatorName == null || "".equals(operatorName)){
				operatorName = "%";
			}
			String delFlag = "%";
			if("True".equals(activeFlag)){
				delFlag = "F";
			}else if("False".equals(activeFlag)){
				delFlag = "T";
			}
			
			List<UserInfo> dbMIList = merchantBusinessService.findMerchantAdminOperatorByNameAndDelFlag(operatorName, delFlag);
			if(dbMIList != null && dbMIList.size()>0){
				List<MerchantOperatorListPageForm> pageList =  MerchantInfoUtil.makeMerchantOperatorListPageForm(dbMIList);
				
				plh = new PagedListHolder<MerchantOperatorListPageForm>(pageList);
				plh.setPage(0);
				plh.setPageSize(10);
				request.getSession().setAttribute("pagedListHolder", plh);
				model.addAttribute("pagedList", plh.getPageList());
			}else{
				request.getSession().setAttribute("pagedListHolder", new PagedListHolder<MerchantOperatorListPageForm>());
			}
		}else if("t".equals(paging)){ // user click page
			String page = request.getParameter("page");
			plh = (PagedListHolder<MerchantOperatorListPageForm>)request.getSession().getAttribute("pagedListHolder");
			if ("next".equals(page)){
				plh.nextPage();
			}else if ("previous".equals(page)){
				plh.previousPage();
			}
			model.addAttribute("pagedList", plh.getPageList());
		}else{ // default
			
		}
		
		return "admin/merchantGroupAdminList";
	}
	@RequestMapping(value="/addMerchantGroupAdminInit", method = {RequestMethod.GET,RequestMethod.POST})
	public String addMerchantGroupAdminInit(@ModelAttribute("addmerchantGroupAdminForm") MerchantGroupAdminInutPageForm mgaipf,Model model,HttpServletRequest request) {
		List<MerchantGroup> dbMGList = merchantBusinessService.findMerchantGroupByName("%");
		model.addAttribute("merchantGroupList",CollectionUtil.transferMerchantGroupList(dbMGList));
		return "admin/addMerchantGroupAdminInit";
	}

	@RequestMapping(value="/addMerchantGroupAdminComplete", method = {RequestMethod.GET,RequestMethod.POST})
	public String addMerchantGroupAdminComplete(@ModelAttribute("addmerchantGroupAdminForm") MerchantGroupAdminInutPageForm mgaipf,Model model,HttpServletRequest request) {
		String operatorName = mgaipf.getOperatorName();
		String password = mgaipf.getPassword();
		String confirmPassword = mgaipf.getConfirmPassword();
		Integer merchantGroupId = mgaipf.getMerchantGroupId();
		
		String resultCode = "SUCCESS";
		String resultReason = "Please continue.";
		
		if(!password.equals(confirmPassword)){
			resultCode = "FAILED";
			resultReason = "Sorry, you have input different password.";
		}else{
			try{
				UserInfo ui = new UserInfo();
				ui.setUserName(operatorName);
				//ui.setRoleId(2);
				ui.setRoleId(4);
				ui.setPassword(MD5Signature.getMD5String(password));
				ui.setMerchantGroup(merchantBusinessService.findMerchantGroupById(merchantGroupId));
				
				merchantBusinessService.save(ui);
			}catch(Exception e){
				resultCode = "FAILED";
				resultReason = e.getMessage();
				e.printStackTrace();
			}
		}
	
		String messageType = "alert-danger";
		if("SUCCESS".equals(resultCode)){
			messageType = "alert-success";
		}
		
		String message = "Your operation result is "+resultCode+". "+resultReason;
		
		model.addAttribute("message",message);
		model.addAttribute("messageType",messageType);
		return "common/result";
	}
	@RequestMapping(value="/updateMerchantGroupAdminInit", method = {RequestMethod.GET,RequestMethod.POST})
	public String updateMerchantGroupAdminInit(@ModelAttribute("updateMerchantGroupAdminForm") MerchantGroupAdminInutPageForm mgaipf,Model model,HttpServletRequest request) {
		List<MerchantGroup> dbMGList = merchantBusinessService.findMerchantGroupByName("%");
		model.addAttribute("merchantGroupList",CollectionUtil.transferMerchantGroupList(dbMGList));
		
		String operatorId = request.getParameter("operatorId");
		UserInfo ui = userService.findUserInfoByUserId(Integer.parseInt(operatorId));
		
		mgaipf.setId(Integer.parseInt(operatorId));
		mgaipf.setOperatorName(ui.getUserName());
		mgaipf.setMerchantGroupId(ui.getMerchantGroup().getId());
		
		return "admin/updateMerchantGroupAdminInit";
	}

	@RequestMapping(value="/updateMerchantGroupAdminComplete", method = {RequestMethod.GET,RequestMethod.POST})
	public String updateMerchantGroupAdminComplete(@ModelAttribute("updateMerchantGroupAdminForm") MerchantGroupAdminInutPageForm mgaipf,Model model,HttpServletRequest request) {
		Integer updateOperatorId = mgaipf.getId();
		UserInfo ui = userService.findUserInfoByUserId(updateOperatorId);
		
		String operatorName = mgaipf.getOperatorName();
		String password = mgaipf.getPassword();
		String confirmPassword = mgaipf.getConfirmPassword();
		Integer merchantGroupId = mgaipf.getMerchantGroupId();
		
		String resultCode = "SUCCESS";
		String resultReason = "Please continue.";
		
		if(!password.equals(confirmPassword)){
			resultCode = "FAILED";
			resultReason = "Sorry, you have input different password.";
		}else{
			try{
				if(password != null && password.isEmpty() && confirmPassword != null && confirmPassword.isEmpty()){
					ui.setUserName(operatorName);
					ui.setMerchantGroup(merchantBusinessService.findMerchantGroupById(merchantGroupId));
				}else if(!password.equals(confirmPassword)){
					resultCode = "FAILED";
					resultReason = "Sorry, you have input different password.";
				}else{
					ui.setUserName(operatorName);
					ui.setMerchantGroup(merchantBusinessService.findMerchantGroupById(merchantGroupId));
					ui.setPassword(MD5Signature.getMD5String(password));
				}
				merchantBusinessService.save(ui);
			}catch(Exception e){
				resultCode = "FAILED";
				resultReason = e.getMessage();
				e.printStackTrace();
			}
		}
	
		String messageType = "alert-danger";
		if("SUCCESS".equals(resultCode)){
			messageType = "alert-success";
		}
		
		String message = "Your operation result is "+resultCode+". "+resultReason;
		
		model.addAttribute("message",message);
		model.addAttribute("messageType",messageType);
		return "common/result";
	}
	
}